package com.ruoyi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.MD5;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.constant.RedisConstants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.system.domain.HyUser;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.mapper.HyUserMapper;
import com.ruoyi.system.service.IHyUserService;
import com.ruoyi.system.service.ISysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 用户信息Service业务层处理
 *
 * @author lixin
 * @date 2021-06-19
 */
@Service
public class HyUserServiceImpl extends ServicePlusImpl<HyUserMapper, HyUser> implements IHyUserService {

	@Autowired
	private RedisCache redisCache;

	@Autowired
	private ISysConfigService configService;

    @Override
    public HyUser queryById(Long userId){
        return baseMapper.selectById(userId);
    }

    @Override
    public TableDataInfo<HyUser> queryPageList(HyUser bo) {
		LambdaQueryWrapper<HyUser> lqw = new LambdaQueryWrapper<HyUser>()
			.eq(StrUtil.isNotBlank(bo.getUserName()), HyUser::getUserName, bo.getUserName())
			.like(StrUtil.isNotBlank(bo.getNickName()), HyUser::getNickName, bo.getNickName());
		return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw));
    }

    @Override
    public List<HyUser> queryList(HyUser bo) {
        return listVo(buildQueryWrapper(bo), HyUser.class);
    }

    private LambdaQueryWrapper<HyUser> buildQueryWrapper(HyUser bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<HyUser> lqw = Wrappers.lambdaQuery();
        lqw.eq(StrUtil.isNotBlank(bo.getUserName()), HyUser::getUserName, bo.getUserName());
        lqw.like(StrUtil.isNotBlank(bo.getNickName()), HyUser::getNickName, bo.getNickName());
        lqw.eq(StrUtil.isNotBlank(bo.getEmail()), HyUser::getEmail, bo.getEmail());
        lqw.eq(StrUtil.isNotBlank(bo.getPhonenumber()), HyUser::getPhonenumber, bo.getPhonenumber());
        lqw.eq(StrUtil.isNotBlank(bo.getQqnumber()), HyUser::getQqnumber, bo.getQqnumber());
        lqw.eq(StrUtil.isNotBlank(bo.getSex()), HyUser::getSex, bo.getSex());
        lqw.eq(bo.getStatus() != null, HyUser::getStatus, bo.getStatus());
        return lqw;
    }

    @Override
    public Boolean insertByAddBo(HyUser bo) {
        HyUser add = BeanUtil.toBean(bo, HyUser.class);
        validEntityBeforeSave(add);
        return save(add);
    }

    @Override
    public Boolean updateByEditBo(HyUser bo) {
        HyUser update = BeanUtil.toBean(bo, HyUser.class);
        validEntityBeforeSave(update);
        return updateById(update);
    }

	/**
	 * 修改用户状态
	 *
	 * @param user 用户信息
	 * @return 结果
	 */
	@Override
	public int updateUserStatus(HyUser user) {
		return baseMapper.updateById(user);
	}

	/**
	 * 根据微信Id查询用户
	 * @param openid
	 * @return
	 */
	@Override
	public HyUser queryByOpenId(String openid) {
		return baseMapper.queryByOpenId(openid);
	}

	/**
	 * 根据昵称查询用户
	 * @param nickName
	 * @return
	 */
	@Override
	public List<HyUser> queryListByNickName(String nickName) {
		return baseMapper.queryListByNickName(nickName);
	}

	/**
	 * 账号密码登录
	 * @param phoneNumber
	 * @param password
	 * @return
	 */
	@Override
	public HyUser login(String phoneNumber, String password) {
		HyUser user = baseMapper.queryByPhonenumber(phoneNumber);
		if(ObjectUtil.isNull(user)) {
			throw new CustomException("手机号不存在");
		}
		if (!StrUtil.equals(SecureUtil.md5(password), user.getPassword())) {
			throw new CustomException("密码错误");
		}
		Date nowTime = DateUtil.date(System.currentTimeMillis());
		user.setLoginTime(nowTime);
		user.setLoginIp(ServletUtils.getClientIP());
		baseMapper.updateById(user);
		return user;
	}

	/**
	 * 验证码登录
	 * @param phoneNumber
	 * @param code
	 * @return
	 */
	@Override
	public HyUser loginByVerificationCode(String phoneNumber, String code) {

		HyUser user = baseMapper.queryByPhonenumber(phoneNumber);
		// 手机号不存在
		if(ObjectUtil.isNull(user)) {
			throw new CustomException("手机号不存在");
		}
		// 验证码校验
		validVerificationCode(phoneNumber, code);

		Date nowTime = DateUtil.date(System.currentTimeMillis());
		user.setLoginTime(nowTime);
		user.setLoginIp(ServletUtils.getClientIP());
		baseMapper.updateById(user);

		return user;
	}

	/**
	 * 用户注册
	 * @param phonenumber
	 * @param password
	 * @param code
	 * @return
	 */
	@Override
	public Boolean register(String phonenumber, String password, String code) {

		// 验证码校验
		validVerificationCode(phonenumber, code);

		HyUser user = new HyUser();
		user.setUserName(phonenumber);
		user.setNickName("hy_" + RandomUtil.randomString(12));
		user.setPhonenumber(phonenumber);
		// 性别：未知
		user.setSex("2");
		user.setAvatar(configService.selectConfigByKey("hy.default.avatarUrl"));
		user.setPassword(SecureUtil.md5(password));
		user.setLoginTime(DateUtil.date(System.currentTimeMillis()));
		user.setLoginIp(ServletUtils.getClientIP());

		return this.save(user);
	}

	/**
	 * 根据电话号码查询用户
	 * @param phonenumber
	 * @return
	 */
	@Override
	public HyUser queryByPhoneNumber(String phonenumber) {
		return baseMapper.queryByPhonenumber(phonenumber);
	}

	/**
	 * 验证码校验
	 * @param phoneNumber
	 * @param code
	 */
	private void validVerificationCode(String phoneNumber, String code){
		String redisKey = RedisConstants.KEY_PREFIX + phoneNumber;

		String redisCode = redisCache.getCacheObject(redisKey);
		if (!StrUtil.equals(code, redisCode)) {
			throw new CustomException("验证码错误");
		}
	}


	/**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(HyUser entity){
        //TODO 做一些数据校验,如唯一约束
    }

    @Override
    public Boolean deleteWithValidByIds(List<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return removeByIds(ids);
    }

}
